package com.gams.websocket.server;

import com.alibaba.fastjson.JSONObject;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelId;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.handler.codec.http.FullHttpRequest;
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;


@Component("clientHandler")
@Scope("prototype")
@Slf4j
@ChannelHandler.Sharable
public class WebSocketServerHandler extends SimpleChannelInboundHandler<Object>
{

    public static ChannelHandlerContext client;

    @Override
    public void channelRead0(ChannelHandlerContext ctx, Object msg)
    {
        if (msg instanceof FullHttpRequest)
        {
            // 传统的HTTP接入
            log.info("FullHttpRequest");
        }
        else if (msg instanceof TextWebSocketFrame)
        {
            //文本消息接入
            sendHeart();
        }
        else if (msg instanceof ByteBuf)
        {
            //二进制流接入
            sendHeart();
        }
        else
        {
            log.info(String.valueOf(msg));
        }
    }

    public void sendHeart()
    {
        JSONObject res = new JSONObject();
        res.put("d", "server");
        res.put("c", "2");
        send(client, JSONObject.toJSONString(res));
    }

    public void sendIDcard(String idcard)
    {
        JSONObject res = new JSONObject();
        res.put("d", idcard);
        res.put("c", "7");
        send(client, JSONObject.toJSONString(res));
    }

    // 0 打印机正常
    //1 打印机未连接或未上电
    //2 打印机和调用库不匹配
    //3 打印头打开
    //4 切刀未复位
    //5 打印头过热
    //6 黑标错误
    //7 纸尽
    //8 纸将尽
    public void send3(int c)
    {
        String msg = "";
        switch (c)
        {
            case 0:
                return;
            case 1:
                msg = "打印机未连接或未上电";
                break;
            case 2:
                msg = "打印机和调用库不匹配";
                break;
            case 3:
                msg = "打印头打开";
                break;
            case 4:
                msg = "切刀未复位";
                break;
            case 5:
                msg = "打印头过热";
                break;
            case 6:
                msg = "黑标错误";
                break;
            case 7:
                msg = "纸尽";
                break;
            case 8:
                msg = "纸将尽";
                break;
            default:
                break;
        }
        JSONObject res = new JSONObject();
        res.put("d", "打印机：" + msg);
        res.put("c", "3");
        send(client, JSONObject.toJSONString(res));
    }

    public void send(ChannelHandlerContext ctx, String msg)
    {
        if (ctx == null)
        {
            log.info("未发现客户端");
            return;
        }
        ctx.channel().writeAndFlush(new TextWebSocketFrame(msg));//向请求客户端输出消息
    }

    @Override
    public void channelReadComplete(ChannelHandlerContext ctx)
    {
        ctx.channel().flush();
    }


    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception
    {
        // 这里是客户端连接成功之后，调用此处，这里可以清除一些已经不在线的客户端ctx
        log.info("Client new id:" + ctx.channel().id());
        client = ctx;
        super.channelActive(ctx);
    }

    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception
    {
        ChannelId id = ctx.channel().id();
        log.info("Client closed id:" + id);
        client = null;
        super.channelInactive(ctx);
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause)
    {
        log.info("Client exception id:" + ctx.channel().id());
        client = null;
        String message = cause.getMessage();
        log.info("error = " + message);
        if (!message.contains("远程主机强迫关闭了一个现有的连接") && !message.contains("Connection reset by peer"))
        {
            cause.printStackTrace();
        }
        ctx.close();
    }


}
